<template>
  <el-dialog
    title="批量导入考核组成"
    :model-value="visible"
    @update:model-value="$emit('update:visible', $event)"
    width="600px"
    :close-on-click-modal="false"
    @close="handleClose"
  >
    <div class="import-content">
      <!-- 导入说明 -->
      <el-alert
        title="导入说明"
        type="info"
        :closable="false"
        style="margin-bottom: 20px;"
      >
        <template #default>
          <p>请上传包含考核组成信息的Excel文件，文件格式要求：</p>
          <ul>
            <li>第一列：考核组成名称（如：平时成绩、期末考试）</li>
            <li>第二列：比例（数字，如：30表示30%）</li>
            <li>第三列：计分方式（如：百分制、五级制等）</li>
            <li>第四列：考核类型（形成性/终结性/其它）</li>
          </ul>
          <p><strong>注意：</strong>所有考核组成的比例总和必须等于100%</p>
        </template>
      </el-alert>

      <!-- 教学任务信息 -->
      <el-card v-if="selectedMission && Object.keys(selectedMission).length > 0" style="margin-bottom: 20px;">
        <template #header>
          <div class="card-header">
            <span>导入目标</span>
          </div>
        </template>
        <el-descriptions :column="2" border>
          <el-descriptions-item label="课程名称">{{ selectedMission.courseName }}</el-descriptions-item>
          <el-descriptions-item label="课程编码">{{ selectedMission.courseCode }}</el-descriptions-item>
          <el-descriptions-item label="学期">{{ selectedMission.termName }}</el-descriptions-item>
          <el-descriptions-item label="教师">
            <span v-if="selectedMission.teacherNames && selectedMission.teacherNames.length > 0">
              {{ selectedMission.teacherNames.join(', ') }}
            </span>
            <span v-else>未分配</span>
          </el-descriptions-item>
        </el-descriptions>
      </el-card>

      <!-- 文件上传 -->
      <el-upload
        ref="uploadRef"
        :auto-upload="false"
        :show-file-list="true"
        :file-list="fileList"
        :on-change="handleFileChange"
        :on-remove="handleFileRemove"
        :before-upload="beforeUpload"
        accept=".xlsx,.xls"
        drag
        style="margin-bottom: 20px;"
      >
        <el-icon class="el-icon--upload"><UploadFilled /></el-icon>
        <div class="el-upload__text">
          将文件拖到此处，或<em>点击上传</em>
        </div>
        <template #tip>
          <div class="el-upload__tip">
            只能上传 .xlsx/.xls 文件，且文件大小不超过5MB
          </div>
        </template>
      </el-upload>

      <!-- 数据预览 -->
      <div v-if="previewData.length > 0" class="preview-section">
        <h4>数据预览 (前5行)</h4>
        <el-table
          :data="previewData.slice(0, 5)"
          border
          size="small"
          style="margin-bottom: 20px;"
        >
          <el-table-column label="考核组成名称" prop="name" min-width="120" resizable />
          <el-table-column label="比例" prop="proportion" width="80" resizable>
            <template #default="scope">
              {{ scope.row.proportion }}%
            </template>
          </el-table-column>
          <el-table-column label="计分方式" prop="scoreTypeName" width="120" resizable />
          <el-table-column label="考核类型" prop="examPartType" width="100" align="center" resizable>
            <template #default="scope">
              <el-tag 
                v-if="scope.row.examPartType === 'FORMATIVE' || scope.row.isFormative" 
                type="success" 
                size="small"
              >
                形成性
              </el-tag>
              <el-tag 
                v-else-if="scope.row.examPartType === 'FINAL' || scope.row.isFinal" 
                type="warning" 
                size="small"
              >
                终结性
              </el-tag>
              <el-tag 
                v-else-if="scope.row.examPartType === 'OTHER'" 
                type="info" 
                size="small"
              >
                其它
              </el-tag>
              <el-tag v-else type="info" size="small">未设置</el-tag>
            </template>
          </el-table-column>
        </el-table>

        <!-- 比例验证 -->
        <el-alert
          :title="`总比例: ${totalProportion}%`"
          :type="totalProportion === 100 ? 'success' : 'error'"
          :description="totalProportion === 100 ? '比例正确，可以导入' : '比例不等于100%，请检查数据'"
          show-icon
          :closable="false"
        />
      </div>
    </div>

    <template #footer>
      <el-button @click="handleCancel">取消</el-button>
      <el-button @click="downloadTemplate" type="info">下载模板</el-button>
      <el-button 
        type="primary" 
        @click="handleImport"
        :loading="importing"
        :disabled="!canImport"
      >
        确定导入
      </el-button>
    </template>
  </el-dialog>
</template>

<script setup>
import { ref, computed, watch } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import { UploadFilled } from '@element-plus/icons-vue'
import * as XLSX from 'xlsx'
import { courseExamPartApi } from '@/api/course-exam-part'
import { scoreTypeApi } from '@/api/score-type'

const props = defineProps({
  visible: {
    type: Boolean,
    default: false
  },
  selectedMission: {
    type: Object,
    default: () => ({})
  }
})

const emit = defineEmits(['update:visible', 'import-success'])

// 响应式数据
const importing = ref(false)
const fileList = ref([])
const previewData = ref([])
const scoreTypes = ref([])
const uploadRef = ref()

// 计算属性
const totalProportion = computed(() => {
  return previewData.value.reduce((sum, item) => sum + (item.proportion || 0), 0)
})

const canImport = computed(() => {
  return previewData.value.length > 0 && 
         totalProportion.value === 100 &&
         props.selectedMission &&
         Object.keys(props.selectedMission).length > 0
})

// 监听文件变化
const handleFileChange = (file, fileList) => {
  if (file.status === 'ready') {
    parseExcelFile(file.raw)
  }
}

const handleFileRemove = () => {
  previewData.value = []
  fileList.value = []
}

const beforeUpload = (file) => {
  const isExcel = file.type === 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' || 
                  file.type === 'application/vnd.ms-excel'
  const isLt5M = file.size / 1024 / 1024 < 5

  if (!isExcel) {
    ElMessage.error('只能上传 Excel 文件!')
    return false
  }
  if (!isLt5M) {
    ElMessage.error('文件大小不能超过 5MB!')
    return false
  }
  return true
}

// 解析Excel文件
const parseExcelFile = async (file) => {
  try {
    await loadScoreTypes()
    
    const reader = new FileReader()
    reader.onload = (e) => {
      try {
        const workbook = XLSX.read(e.target.result, { type: 'array' })
        const firstSheetName = workbook.SheetNames[0]
        const worksheet = workbook.Sheets[firstSheetName]
        const jsonData = XLSX.utils.sheet_to_json(worksheet, { header: 1 })
        
        // 跳过标题行，从第二行开始解析数据
        const dataRows = jsonData.slice(1).filter(row => row.length > 0)
        
        const parsedData = dataRows.map((row, index) => {
          try {
            const name = String(row[0] || '').trim()
            const proportion = parseFloat(row[1]) || 0
            const scoreTypeName = String(row[2] || '').trim()
            const examPartTypeText = String(row[3] || '').toLowerCase().trim()
            
            // 解析考核类型
            let examPartType = 'OTHER'
            if (['形成性', 'formative', '形成性考核'].includes(examPartTypeText)) {
              examPartType = 'FORMATIVE'
            } else if (['终结性', 'final', '终结性考核'].includes(examPartTypeText)) {
              examPartType = 'FINAL'
            } else if (['其它', 'other', '其他'].includes(examPartTypeText)) {
              examPartType = 'OTHER'
            }
            
            // 为了兼容旧格式，也检查是/否格式
            const isFormative = ['是', 'true', '1', 'yes'].includes(examPartTypeText) || examPartType === 'FORMATIVE'
            const isFinal = examPartType === 'FINAL'

            // 查找对应的计分方式ID
            const scoreType = scoreTypes.value.find(type => type.name === scoreTypeName)
            
            if (!name) {
              throw new Error('考核组成名称不能为空')
            }
            if (proportion <= 0 || proportion > 100) {
              throw new Error('比例必须在1-100之间')
            }
            if (!scoreType) {
              throw new Error(`未找到计分方式: ${scoreTypeName}`)
            }

            return {
              name,
              proportion,
              scoreTypeId: scoreType.id,
              scoreTypeName: scoreType.name,
              examPartType,
              isFormative,
              isFinal,
              teachingMissionId: props.selectedMission.id
            }
          } catch (error) {
            throw new Error(`第${index + 2}行数据错误: ${error.message}`)
          }
        })

        previewData.value = parsedData
        ElMessage.success(`成功解析 ${parsedData.length} 条数据`)
        
      } catch (error) {
        console.error('解析Excel文件失败:', error)
        ElMessage.error(`解析Excel文件失败: ${error.message}`)
        previewData.value = []
      }
    }
    
    reader.readAsArrayBuffer(file)
  } catch (error) {
    console.error('读取文件失败:', error)
    ElMessage.error('读取文件失败')
  }
}

// 加载计分方式
const loadScoreTypes = async () => {
  try {
    const response = await scoreTypeApi.getAllScoreTypes()
    scoreTypes.value = response.data || []
  } catch (error) {
    console.error('获取计分方式失败:', error)
    ElMessage.error('获取计分方式失败')
  }
}

// 下载模板
const downloadTemplate = () => {
  // 创建模板数据
  const templateData = [
    ['考核组成名称', '比例', '计分方式', '是否形成性考核', '是否终结性考核'],
    ['平时成绩', 30, '百分制', '是', '否'],
    ['期中考试', 30, '百分制', '否', '是'],
    ['期末考试', 40, '百分制', '否', '是']
  ]

  // 创建工作簿
  const worksheet = XLSX.utils.aoa_to_sheet(templateData)
  const workbook = XLSX.utils.book_new()
  XLSX.utils.book_append_sheet(workbook, worksheet, '考核组成模板')

  // 下载文件
  XLSX.writeFile(workbook, '考核组成导入模板.xlsx')
  ElMessage.success('模板下载成功')
}

// 执行导入
const handleImport = async () => {
  if (!canImport.value) {
    ElMessage.warning('请检查数据后再导入')
    return
  }

  try {
    await ElMessageBox.confirm(
      `确定要导入 ${previewData.value.length} 条考核组成数据吗？导入后将覆盖现有配置。`,
      '确认导入',
      {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning',
      }
    )

    importing.value = true
    
    // 调用API保存数据
    await courseExamPartApi.saveExamParts(props.selectedMission.id, previewData.value)
    
    ElMessage.success('导入成功')
    emit('import-success')
    handleClose()
    
  } catch (error) {
    if (error !== 'cancel') {
      console.error('导入失败:', error)
      ElMessage.error(`导入失败: ${error.message || '未知错误'}`)
    }
  } finally {
    importing.value = false
  }
}

// 关闭对话框
const handleClose = () => {
  emit('update:visible', false)
  // 重置数据
  previewData.value = []
  fileList.value = []
}

const handleCancel = () => {
  if (previewData.value.length > 0) {
    ElMessageBox.confirm(
      '关闭将丢失已解析的数据，确定关闭吗？',
      '确认关闭',
      {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning',
      }
    ).then(() => {
      handleClose()
    }).catch(() => {
      // 用户取消，不做任何操作
    })
  } else {
    handleClose()
  }
}

// 监听对话框显示状态
watch(() => props.visible, (newVal) => {
  if (newVal) {
    loadScoreTypes()
  }
})
</script>

<style scoped>
.import-content {
  max-height: 70vh;
  overflow-y: auto;
}

.preview-section {
  margin-top: 20px;
}

.preview-section h4 {
  margin-bottom: 10px;
  color: #303133;
  font-size: 16px;
  font-weight: 600;
}

.card-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.el-upload__tip {
  color: #909399;
  font-size: 12px;
  line-height: 1.5;
  margin-top: 7px;
}

.el-upload .el-icon--upload {
  font-size: 67px;
  color: #c0c4cc;
  margin: 40px 0 16px;
  line-height: 50px;
}

.el-upload__text {
  color: #606266;
  font-size: 14px;
  text-align: center;
}

.el-upload__text em {
  color: #409eff;
  font-style: normal;
}

:deep(.el-descriptions__body) {
  background-color: #fafafa;
}

:deep(.el-alert__content) {
  padding-left: 8px;
}

:deep(.el-alert ul) {
  margin: 8px 0;
  padding-left: 20px;
}

:deep(.el-alert li) {
  margin: 4px 0;
  list-style-type: disc;
}
</style>
